// 金牛座接口封装
import type { AxiosResponse, AxiosRequestConfig } from 'axios';
import { ContentTypeEnum } from '/@/enums/httpEnum';
import { setToken as setAutoToken, getToken as getAutoToken } from '@/utils/auth';
import { showLoading, hideLoading } from '@/utils/loading';
import useUserStore from '@/store/modules/user';
import { ElMessage, ElNotification } from 'element-plus';
import { createAxios } from '@/utils/http/axios/index';
import { clone } from 'lodash-es';
import type { RequestOptions } from '/#/axios';

const AutoToken = 'Auto-Token';
// 不获取对象第一个键值的接口列表
const noGetObjFirstKeyList = ['/echo'];

/**
 * @description: 金牛座数据处理
 */
const transform = {
  /**
   * @description: 处理响应数据
   */
  transformResponseHook: (response: AxiosResponse<any>, options: any) => {
    hideLoading();
    // 获取响应数据
    let currentAutoData = response.data;
    // 非文件类型
    if (
      response.config.responseType !== 'blob' &&
      typeof currentAutoData == 'object' &&
      !noGetObjFirstKeyList.some((item) => response.request.responseURL.includes(item))
    ) {
      // 多了一个 request_id
      if (currentAutoData.request_id) {
        delete currentAutoData.request_id;
      }
      const keys = Object.values(currentAutoData);
      // 单表操作直接平铺数据方便页面中取值
      if (keys.length === 1 || !response.config.url?.includes('/crud')) {
        currentAutoData = Object.values(currentAutoData)[0];
      } else {
        //crud方法如果存在多表操作时  处理无法正常使用，返回原始数据
        return Promise.resolve(response.data);
      }
    }

    return currentAutoData;
  },

  /**
   * @description: 请求拦截器处理
   */
  requestInterceptors: (config: any, options: any) => {
    // 显示加载动画
    const noLoading = config.requestOptions?.noLoading;
    if (!noLoading) {
      showLoading();
    }

    // 使用标准的withToken配置
    const withToken = (config.requestOptions || {}).withToken !== false;

    // 设置token
    if (getAutoToken(AutoToken) && withToken) {
      config.headers.Authorization = options.authenticationScheme
        ? `${options.authenticationScheme} ${getAutoToken(AutoToken)}`
        : getAutoToken(AutoToken);
      config.headers['x-token'] = getAutoToken(AutoToken);
    }

    return config;
  },

  /**
   * @description: 响应错误处理
   */
  responseInterceptorsCatch: (axiosInstance: any, error: any) => {
    hideLoading();
    const { response, message, config } = error || {};
    const route = useRoute();
    // 金牛座特有的错误处理逻辑
    if (message === 'Request failed with status code 401' && response) {
      // 暂存初始请求
      const originalRequest = response.config;
      // 设置状态码
      const status = response.status;
      // 获取错误信息
      const msg = response.data?.msg;

      if (status === 401 && !originalRequest._retry) {
        originalRequest._retry = true;

        // 尝试刷新token
        return new Promise((resolve, reject) => {
          autoService
            .post<any>(
              {
                url: '/get_token',
                data: {
                  id: 'jiaoyupeixun',
                },
              },
              {
                withToken: false,
                noLoading: true, // 刷新token请求不显示loading
              } as RequestOptions,
            )
            .then((newToken) => {
              // 更新token
              setAutoToken(newToken, AutoToken);
              // 重新发起原来的请求
              resolve(axiosInstance(originalRequest));
            })
            .catch((error) => {
              // 刷新token失败，登出并跳转登录页
              console.log('刷新token失败:', error);

              useUserStore()
                .logOut()
                .then(() => {
                  if (route.meta.isAdmin) {
                    location.href = '/login';
                  } else {
                    location.href = '/';
                  }
                });

              reject(msg || '无效的会话，或者会话已过期，请重新登录。');
            });
        });
      }
    } else if (message === '数据正在处理，请勿重复提交') {
      ElMessage({ message, type: 'error', duration: 2 * 1000 });
      return Promise.resolve({}); // 返回空对象避免进一步错误
    } else if (response?.status === 500) {
      ElNotification.error({ title: '数据异常，请联系管理员' });
      return Promise.reject();
    } else if (response) {
      if (!config?.requestOptions?.noHandleError) {
        ElNotification.error({ title: response.data?.message || '请求失败' });
      }
      return Promise.reject('error');
    }

    // 其他错误交给默认处理
    return Promise.reject(error);
  },
};

// 为金牛座API创建独立的axios实例，不会影响默认实例
const autoService = createAxios({
  baseURL: import.meta.env.VITE_APP_AUTO_API,
  timeout: 999999,
  headers: { 'Content-Type': ContentTypeEnum.JSON },
  transform: clone(transform), // 使用clone确保不会修改原始transform
  requestOptions: {
    withToken: true,
    ignoreCancelToken: true,
    formatDate: true,
  },
});

/**
 * @description: 金牛座Post请求简化方法
 */
export const autoPost = function <T = any>(
  url: string,
  data: Record<string, any>,
  config?: AxiosRequestConfig,
  options?: RequestOptions,
) {
  return autoService.post<T>(
    {
      url,
      data,
      ...(config || {}),
    },
    options,
  );
};

export default autoService;
